<template>
  <n-card>
    <!--菜单查询-->
    <n-form inline :model="queryParams" label-placement="left">
      <n-form-item label="菜单名称" path="name">
        <n-input v-model:value="queryParams.name" :clearable="true" />
      </n-form-item>
      <n-form-item label="菜单状态" path="name">
        <n-select
          v-model:value="queryParams.isShow"
          style="width: 160px"
          :options="viewTypeDict"
          :clearable="true"
        />
      </n-form-item>
      <n-form-item>
        <n-button attr-type="button" @click="reloadTable">查询</n-button>
      </n-form-item>
    </n-form>

    <!--页面表格信息-->
    <BasicTable
      :columns="columns"
      :request="loadDataTable"
      :row-key="(row) => row.id"
      ref="actionTableRef"
      :actionColumn="actionColumn"
      :pagination="false"
      v-model:checked-row-keys="checkedRowKeys"
    >
      <template #tableTitle>
        <n-button type="primary" @click="onOpenAddMenuModal">新增菜单</n-button>
      </template>
      <template #toolbar> </template>
    </BasicTable>

    <!--新增或修改职位-->
    <n-modal
      :show-icon="false"
      v-model:show="modelInfo.show"
      preset="dialog"
      :title="modelInfo.info.id ? '修改部门' : '新增部门'"
      width="800px"
      style="width: 600px"
    >
      <n-form
        :model="modelInfo.info"
        ref="menuFormRef"
        label-placement="left"
        :label-width="80"
        :rules="menuFormRules"
      >
        <n-grid :cols="24" x-gap="10">
          <n-form-item-gi :span="24" label="上级菜单" path="parentId">
            <n-tree-select
              v-model:value="modelInfo.info.parentId"
              :options="menuTree"
              label-field="name"
              key-field="id"
              children-field="children"
            />
          </n-form-item-gi>
          <n-form-item-gi :span="24" label="菜单类型">
            <n-radio-group v-model:value="modelInfo.info.menuType">
              <n-space>
                <n-radio v-for="item in menuTypeDict" :key="item.value" :value="item.value">
                  {{ item.label }}
                </n-radio>
              </n-space>
            </n-radio-group>
          </n-form-item-gi>

          <n-form-item-gi :span="12" label="菜单名称" path="name">
            <n-input
              placeholder="菜单名称"
              v-model:value="modelInfo.info.name"
              :step="1"
              :min="0"
            />
          </n-form-item-gi>
          <n-form-item-gi :span="12" label="显示排序" path="treeSort">
            <n-input-number
              placeholder="排序"
              v-model:value="modelInfo.info.treeSort"
              :step="1"
              :min="0"
            />
          </n-form-item-gi>
          <n-form-item-gi
            v-if="modelInfo.info.menuType != 'BUTTON'"
            :span="12"
            label="路由地址"
            path="menuUrl"
          >
            <n-input
              placeholder="路由地址"
              v-model:value="modelInfo.info.menuUrl"
              :step="1"
              :min="0"
            />
          </n-form-item-gi>
          <n-form-item-gi
            v-if="modelInfo.info.menuType == 'MENU'"
            :span="12"
            label="组件地址"
            path="componentPath"
          >
            <n-input
              placeholder="组件地址"
              v-model:value="modelInfo.info.componentPath"
              :step="1"
              :min="0"
            />
          </n-form-item-gi>
          <n-form-item-gi :span="12" label="权限标识" path="menuWeb">
            <n-input placeholder="权限标识" v-model:value="modelInfo.info.menuWeb" />
          </n-form-item-gi>
          <n-form-item-gi
            v-if="modelInfo.info.menuType != 'BUTTON'"
            :span="12"
            label="显示状态"
            path="menuWeb"
          >
            <n-radio-group v-model:value="modelInfo.info.isShow">
              <n-space>
                <n-radio v-for="item in viewTypeDict" :key="item.value" :value="item.value">
                  {{ item.label }}
                </n-radio>
              </n-space>
            </n-radio-group>
          </n-form-item-gi>
          <n-form-item-gi
            v-if="modelInfo.info.menuType == 'MENU'"
            :span="12"
            label="是否缓存"
            path="menuWeb"
          >
            <n-radio-group v-model:value="modelInfo.info.keepAlive">
              <n-space>
                <n-radio v-for="item in yesNoDict" :key="item.value" :value="item.value">
                  {{ item.label }}
                </n-radio>
              </n-space>
            </n-radio-group>
          </n-form-item-gi>
          <n-form-item-gi
            v-if="modelInfo.info.menuType != 'BUTTON'"
            :span="12"
            label="菜单图标"
            path="menuWeb"
          >
            <n-input placeholder="菜单图标" v-model:value="modelInfo.info.menuIcon" />
          </n-form-item-gi>
          <n-form-item-gi
            v-if="modelInfo.info.menuType == 'DIRECTORY'"
            :span="12"
            label="重定向地址"
            path="menuWeb"
          >
            <n-input placeholder="重定向地址" v-model:value="modelInfo.info.redirect" />
          </n-form-item-gi>
          <n-form-item-gi
            v-if="modelInfo.info.menuType != 'BUTTON'"
            :span="12"
            label="后台地址"
            path="menuHref"
          >
            <n-input placeholder="后台地址" v-model:value="modelInfo.info.menuHref" />
          </n-form-item-gi>
          <n-form-item-gi
            v-if="modelInfo.info.menuType != 'BUTTON'"
            :span="12"
            label="请求方式"
            path="menuHref"
          >
            <n-select
              placeholder="请求方式"
              v-model:value="modelInfo.info.menuIcon"
              :options="requestTypeDict"
            />
          </n-form-item-gi>
        </n-grid>
      </n-form>
      <template #action>
        <n-space>
          <n-button @click="modelInfo.show = false">取消</n-button>
          <n-button type="info" @click="onAddOrEditMenu">确认</n-button>
        </n-space>
      </template>
    </n-modal>
  </n-card>
</template>

<script lang="tsx" setup>
  import { h, ref, reactive } from 'vue';
  import { BasicTable, TableAction } from '@/components/Table';
  import { useInitDict } from '@/hooks/dictHooks';
  import { NTag, NButton } from 'naive-ui';
  import { getTreeByEntityApi, addDeptApi, modifyDeptApi, deleteDeptApi } from '@/api/system/dept';
  import { addMenuApi, modifyMenuApi, deleteMenuApi, getMenuTreeApi } from '@/api/system/menu';
  import { debounce, deleteNullChildren, structureParams } from '@/utils';

  import { activeColumnHooks } from '@/hooks/activeColumnHooks';
  import { messageHooks } from '@/hooks/baseHooks';

  const { message, IDialog } = messageHooks();
  const actionTableRef = ref();
  const menuFormRef = ref();
  const menuFormRules = reactive({
    parentId: [{ required: true, message: '上级菜单不能为空', trigger: 'blur' }],
    name: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],
    treeSort: [{ required: true, message: '显示排序不能为空', trigger: 'blur', type: 'number' }],
  });
  const menuTree = ref([]);

  let modelInfo = reactive({
    show: false,
    info: {},
  }); //显示新增修改弹窗

  function resetModelInfo() {
    modelInfo.show = false;
    modelInfo.info = {
      id: undefined, // 菜单ID
      name: undefined, // 菜单名称
      parentId: '1000000000000000001', // 上级ID
      treeSort: 0, // 排序
      menuIcon: undefined, // 图标
      menuUrl: undefined, // 路由地址
      componentPath: undefined, // 组件路径
      menuType: 'DIRECTORY', // 菜单类型（M目录 C菜单 F按钮）
      isShow: 'SHOW',
      menuWeb: undefined,
      menuHref: undefined,
      method: undefined,
      redirect: undefined,
      keepAlive: 'YES',
    };
    onGetTreeMenu();
  }

  /**
   * 获取菜单tree数据
   */
  function onGetTreeMenu() {
    getMenuTreeApi({}).then((res) => {
      if (res && res.code === 'A00000') {
        menuTree.value = [
          {
            id: '1000000000000000001',
            name: '主菜单',
            children: deleteNullChildren(res.data),
          },
        ];
      }
    });
  }

  //初始化数据字典
  const { menuTypeDict, viewTypeDict, yesNoDict, requestTypeDict } = useInitDict({
    MENU_TYPE: 'menuTypeDict',
    VIEW_TYPE: 'viewTypeDict',
    YES_NO: 'yesNoDict',
    REQUEST_TYPE: 'requestTypeDict',
  });

  //定义查询条件
  const queryParams = reactive({
    name: undefined,
    status: undefined,
  });

  //查询表格数据
  function reloadTable() {
    actionTableRef.value.refresh(true);
  }

  //定义表格多选中项
  const checkedRowKeys = ref([]);

  //表格列配置
  const columns = [
    {
      title: '菜单名称',
      key: 'name',
    },
    {
      title: '排序',
      key: 'treeSort',
    },
    {
      title: '权限标识',
      key: 'menuWeb',
    },
    {
      title: '组件路径',
      key: 'componentPath',
    },
    {
      title: '显示状态',
      key: 'isShow',
      render(row) {
        return row.isShow === 'SHOW' ? (
          <NTag type="success">显示</NTag>
        ) : (
          <NTag type="error">隐藏</NTag>
        );
      },
    },
  ];

  //表格操作列配置
  const { actionColumn } = activeColumnHooks(handleDelete, onOpenEditMenu);

  //加载表格数据方法
  const loadDataTable = async () => {
    let params = {
      ...queryParams,
    };

    const res = await getMenuTreeApi(structureParams(params));

    return deleteNullChildren(res.data);
  };

  //点击修改按钮
  function onOpenEditMenu(record: Recordable) {
    resetModelInfo();
    modelInfo.info = { ...record };
    modelInfo.show = true;
  }

  //点击删除按钮
  function handleDelete(record: Recordable) {
    IDialog.success('你确定删除当前菜单？', () => {
      deleteMenuApi(record).then((res) => {
        if (res && res.code === 'A00000') {
          reloadTable();
          message.success(res.msg);
        } else {
          message.error(res.msg);
        }
      });
    });
  }

  //打开新增菜单页面
  function onOpenAddMenuModal() {
    resetModelInfo();
    modelInfo.show = true;
  }

  const onAddOrEditMenu = debounce(function () {
    menuFormRef.value.validate((errors) => {
      if (!errors) {
        if (modelInfo.info.id === undefined) {
          // 新增菜单
          addMenuApi(modelInfo.info).then((res) => {
            if (res.code === 'A00000') {
              message.success(res.msg);
              modelInfo.show = false;
              reloadTable();
            } else {
              console.log('modify failed');
              message.error(res.msg);
            }
          });
        } else {
          // 修改菜单
          modifyDeptApi(modelInfo.info).then((res) => {
            if (res.code === 'A00000') {
              message.success(res.msg);
              modelInfo.show = false;
              reloadTable();
            } else {
              message.error(res.msg);
            }
          });
        }
      }
    });
  });
</script>

<style scoped></style>
